package com.whsxt.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whsxt.common.CodeMsg;
import com.whsxt.common.Constants;
import com.whsxt.domain.User;
import com.whsxt.dto.UserDto;
import com.whsxt.exception.BusinessException;
import com.whsxt.mapper.UserMapper;
import com.whsxt.service.UserService;
import com.whsxt.utils.Md5PasswordUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Set;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    /**
     * 根据用户名查询出用户实体对象
     *
     * @param username
     * @return
     */
    @Override
    public User loadUserByUsername(String username) {
        return userMapper.selectUserByUsername(username);
    }


    /**
     * 分页查询用户的数据
     * @param userDto
     */
    @Override
    public PageInfo<User> findPage(UserDto userDto) {

        Page<Object> objects = PageHelper.startPage(userDto.getPage(), userDto.getLimit());
        List<User> list = userMapper.selectUserPage(userDto);
        PageInfo<User> userPageInfo = new PageInfo<>(list);
        userPageInfo.setTotal(objects.getTotal());
        return userPageInfo;
    }

    /**
     * 通过id批量删除用户的信息
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public boolean batchDelete(List<Integer> ids) {
        int rows = userMapper.deleteByIds(ids);
        return rows > 0 ? true:false;
    }

    /**
     * 新增用户
     * @param userDto
     * @return
     */
    @Override
    public boolean save(UserDto userDto) {
        // 添加用户数据步骤
        // 1.校验数据
        validate(userDto);
        // 2.属性的copy 使用BeanUtils
        User user = new User();
        // 复制的原则：1.属性的名称要完全对应 2.属性的类型要完全对应
        BeanUtils.copyProperties(userDto, user);
        // 3. 填充默认值
        user.setCreateTime(new Date());
        user.setDeleted(Constants.DEFAULT_DELETED);
        user.setLoginPassword(Md5PasswordUtils.encode(user.getLoginPassword()));
        // 4. 完成添加用户操作
        int rows = userMapper.insert(user);
        return rows > 0;
    }

    /**
     * 修改用户信息
     * @param userDto
     * @return
     */
    @Override
    public boolean update(UserDto userDto) {
        // 先查询用户数据是否存在
        Integer id = userDto.getId();
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null){
            throw new IllegalArgumentException("您修改的用户数据不存在");
        }

        // 数据校验
        if(!userDto.getLoginName().equals(user.getLoginName())){
            throw new IllegalArgumentException("用户名不一致");
        }

        // 比较修改的密码
        String newPwd = Md5PasswordUtils.encode(userDto.getNewPassword());
        String oldPwd = user.getLoginPassword();
        String inputOldPwd = Md5PasswordUtils.encode(userDto.getOldPassword());

        if(!oldPwd.equals(inputOldPwd)){
            throw new IllegalArgumentException("输入的密码不一致");
        }

        if(newPwd.equals(oldPwd)){
            throw new IllegalArgumentException("修改的密码不应该与之前的密码一致");
        }
        User user1 = new User();
        // copy属性
        BeanUtils.copyProperties(userDto, user1);
        user1.setLoginPassword(newPwd);

        // 设置删除的时间
        if(userDto.getDeleted() == 0){
            user1.setDeleteTime(new Date());
        }

        // 修改用户数据
        int rows = userMapper.updateByPrimaryKeySelective(user1);

        return rows > 0;
    }

    /**
     * 修改用户的禁用状态
     *
     * @param id
     * @return
     */
    @Override
    public boolean updateDeleted(Integer id) {
        // 先通过id 查询用户是否存在
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null){
            throw new IllegalArgumentException("用户不存在");
        }
        // 填充属性
        Integer deleted = user.getDeleted();
        User update = new User();
        update.setId(id);
        update.setDeleted(user.getDeleted() == 1 ? 0 : 1);
        update.setDeleteTime(update.getDeleted() == 0? new Date(): null);
        // 修改
        int rows = userMapper.updateByPrimaryKeySelective(update);

        return rows > 0;
    }

    /**
     * 为用户分配角色
     * @param userId
     * @param roleIds
     * @return
     */
    @Override
    @Transactional
    public boolean assign(Integer userId, Integer[] roleIds) {
        // 维护两张中间表的关系简单步骤：
        // 1.删除此用户所有角色id,
        int deleteRows = userMapper.deleteRoleByUserId(userId);
        // 2.再往关系表中添加数据
        int assignRows = 0;
        if(roleIds.length != 0 && roleIds != null){
            assignRows = userMapper.assign(userId, roleIds);
        }
        return deleteRows + assignRows > 0;
    }

    /**
     * 对前端数据的校验
     * 校验数据(数据数值校验 和 逻辑校验)
     * 1 数据数值校验 为空，范围，规则
     * 2 数据的逻辑： 是否能重复
     * @param userDto
     */
    public void validate(UserDto userDto){
        // 1.校验数据
        // 校验数据不能为空
        if(!StringUtils.hasText(userDto.getLoginName())){
            throw new IllegalArgumentException("用户登录名不能为空");
        }

        if(!StringUtils.hasText(userDto.getRealname())){
            throw new IllegalArgumentException("用户真实姓名不能为空");
        }

        if(!StringUtils.hasText(userDto.getIdCard())){
            throw new IllegalArgumentException("用户证件号码不能为空");
        }

        if(!StringUtils.hasText(userDto.getPhone())){
            throw new IllegalArgumentException("用户手机号不能为空");
        }

        if(userDto.getLoginPassword().length() < 6){
            throw new IllegalArgumentException("登录名的长度必须大于6位");
        }

        // 2.数据的逻辑
        String loginName = userDto.getLoginName();
        Integer count = userMapper.selectCountByUsername(loginName);
        if(count > 0){
            // 逻辑异常一般自定义异常
            throw new BusinessException(CodeMsg.USER_NAME_FOUND, userDto.getLoginName());
        }
    }

}
